#include "mq_connection.hpp"

using namespace xzt;

// 定义回调函数
void cb(const Channel::ptr& channel, const std::string &tag, const xzt::BasicPropeties *bp, const std::string &body)
{
    ILOG("## %s 消费了消息: %s ##", tag.c_str(), body.c_str());
    // 确认消息
    channel->basicAck(bp->id());
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        ILOG("Usage:./consume_client <queue_name>");
        return -1;
    }

    // 1.实例化异步工作对象
    AsyncWorker::ptr worker = std::make_shared<AsyncWorker>();
    // 2.实例化connection对象
    Connection::ptr conn = std::make_shared<Connection>("127.0.0.1", 8085, worker);
    // 3.通过连接创建信道
    Channel::ptr ch = conn->openChannel();
    // 4.通过信道完成服务
    // <1> 声明一个交换机，类型为广播类型
    google::protobuf::Map<std::string, std::string> args;
        // 广播模式
    //ch->declareExchange("exchange1", ExchangeType::FANOUT, true, false, args);
        // 直连模式
    //ch->declareExchange("exchange1", ExchangeType::DIRECT, true, false, args);
        // 主题模式
    ch->declareExchange("exchange1", ExchangeType::TOPIC, true, false, args);
    // <2> 声明队列queue1和queue2
    ch->declareQueue("queue1", true, false, false, args);
    ch->declareQueue("queue2", true, false, false, args);
    // <3> 绑定队列到交换机
        // 广播模式和直连模式
    //ch->queueBind("exchange1", "queue1", "queue1");
        // 主题模式
    ch->queueBind("exchange1", "queue1", "news.#");
    ch->queueBind("exchange1", "queue2", "news.music.#");

    // 5.订阅指定队列
    auto functor = std::bind(cb, ch, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
    ch->basicConsume("consumer1", argv[1], false, functor);

    while(true)
    {
        DLOG("Waiting for messages...");
        std::this_thread::sleep_for(std::chrono::seconds(5));
    }

    // 6.关闭信道
    conn->closeChannel(ch);
    return 0;
}